/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DataLayer.KnowledgeBase;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.imageio.ImageIO;

/**
 *
 * @author csigabiga
 */
public class KnowledgeBaseControl implements IKnowledgeBaseControl {

    KnowledgeBase kBase;
    String knowledgeBasePath = "./know.kb";

    /**
     * The constructor.
     */
    public KnowledgeBaseControl() {
        kBase = new KnowledgeBase();
        loadKnowledgeBase(knowledgeBasePath);
    }

    /**
     * Returns the knowledgebase.
     * @return - The knowledgebase.
     */
    public KnowledgeBase getKnowledgeBase()
    {
        return kBase;
    }

    /**
     * Loads a knowledgebase from the path specified
     * @param path - The path.
     */
    public void loadKnowledgeBase(String path) {
        knowledgeBasePath = path;
        ObjectInputStream in = null;
        try {
            File f = new File(knowledgeBasePath);
            if (f.exists())
            {
                in = new ObjectInputStream(new FileInputStream(new File(knowledgeBasePath)));
                kBase = (KnowledgeBase) in.readObject();
            }
            else
            {
                System.out.println("KB does not exist");
            }
        } catch (ClassNotFoundException ex) {
            System.out.print(ex);
        } catch (IOException ex) {
            System.out.print(ex);
        }
    }

    /**
     * Loads and merges knowledgebase from the path specified
     * @param path - The path.
     */
    public void loadAndMergeKnowledgeBase(String path) {
        KnowledgeBase secondKBase = null;
        ObjectInputStream in = null;
        try {
            in = new ObjectInputStream(new FileInputStream(new File(path)));
            secondKBase = (KnowledgeBase) in.readObject();
        } catch (ClassNotFoundException ex) {
            System.out.print(ex);
        } catch (IOException ex) {
            System.out.print(ex);
        } finally {
            try {
                in.close();
            } catch (IOException ex) {
                System.out.print(ex);
            }

            mergeKnowledgeBase(secondKBase);
        }
    }

    /**
     * Merges the actual knowledgebase withe the one in the parameterlist.
     * @param secondKBase - The knowledgebase.
     */
    public void mergeKnowledgeBase(KnowledgeBase secondKBase)
    {
        for (char ch = 'a'; ch <= 'z'; ++ch)
        {
            SingleCharInfos sInfo = secondKBase.charInfoMap.get(Character.toString(ch));
            kBase.charInfoMap.get(Character.toString(ch)).imgList.putAll(sInfo.imgList);
            kBase.charInfoMap.get(Character.toString(ch)).avg = sInfo.avg; //not precise
        }
        for (char ch = 'A'; ch <= 'Z'; ++ch)
        {
            SingleCharInfos sInfo = secondKBase.charInfoMap.get(Character.toString(ch));
            kBase.charInfoMap.get(Character.toString(ch)).imgList.putAll(sInfo.imgList);
            kBase.charInfoMap.get(Character.toString(ch)).avg = sInfo.avg;
        }
    }

    /**
     * Writes the knowledgebase to the hard drive.
     * @return
     */
    public boolean exportKnowledgeBase(String exportPath)
    {
        ObjectOutputStream out = null;
        try
        {
            //out = new ObjectOutputStream(new FileOutputStream(new File(knowledgeBasePath)));
            if(!exportPath.endsWith(".kb")){
                exportPath +=".kb";
            }
            out = new ObjectOutputStream(new FileOutputStream(new File(exportPath)));
            out.writeObject(kBase);
        } 
        catch (IOException ex)
        {
            System.out.print(ex);
            return false;
        } 
        finally
        {
            try
            {
                out.close();
                return true;
            } 
            catch (IOException ex)
            {
                System.out.print(ex);
                return false;
            }
        }
    }

    /**
     * Transforms the knowledgebase into a file directory and saves it.
     */
    public void transformKnowledgeBase() {
        int n = kBase.charInfoMap.size();

        Set s = kBase.charInfoMap.entrySet();
        Iterator it = s.iterator();

        String baseDir = "./KnowledgeBase";
        File f = new File(baseDir);
        f.mkdir();

        while (it.hasNext()) {
            // key=value separator this by Map.Entry to get key and value
            Map.Entry m = (Map.Entry) it.next();

            // getKey is used to get key of Map
            String key = (String) m.getKey();

            // getValue is used to get value of key in Map
            SingleCharInfos value = (SingleCharInfos) m.getValue();

            int val = key.charAt(0);
            File subdir = new File(baseDir + "\\" + key + "_" + val);
            subdir.mkdir();

            int i = 0;
            for ( SerializableBufferedImage img : value.imgList.values())
            {
                i++;
                String format = "png";
                try {
                    ImageIO.write(img.getBufferedImage(), format, new File(baseDir + "\\" + key + "_" + val + "\\" + key + "_" + img.getID() + "." + format));
                } catch (IOException ex) {
                    System.out.println(ex);
                }
            }

            String format = "png";
            try {
                if (value.avg.getBufferedImage() != null)
                    ImageIO.write(value.avg.getBufferedImage(), format, new File(baseDir + "\\" + key + "_" + val + "\\" + key + "__avg__" + "." + format));
            } catch (IOException ex) {
                System.out.println(ex);
            }
        }


    }
}
